///////////////////////////////////////////////////////////////////////////////
//
// aluTermIoAttr.cc - class for terminal I/O
// 
// 1st release: A. Lusiani <a.lusiani@sns.it> April 2005
//

///////////////////////////////////////////////////////////////////////////////
//
// headers
//

extern "C" {
#include <stdio.h>
#include <termios.h>
#include <string.h>
}

#include "aluTermIoAttr.h"

///////////////////////////////////////////////////////////////////////////////
//
// methods 
//

//--- default constructor
aluTermIoAttr::aluTermIoAttr()
{
  isTerminal = false;
  fn = fileno(stdin);
  //--- init terminal attributes struct private member for stdin
  if (tcgetattr(fn, &attr) == 0) {
    //--- annotate whether the file handler corresponds to a terminal
    isTerminal = true;
  }
  printf("isTerminal %d, fn=%d\n", isTerminal?1:0, fn);
}

//--- constructor with file handler argument
aluTermIoAttr::aluTermIoAttr(FILE *input)
{
  isTerminal = false;
  fn = fileno(input);
  //--- init terminal attributes struct private member for stdin
  if (tcgetattr(fn, &attr) == 0) {
    //--- annotate whether the file handler corresponds to a terminal
    isTerminal = true;
  }
  printf("isTerminal %d, fn=%d\n", isTerminal?1:0, fn);
}

//--- constructor with file handler argument
aluTermIoAttr::aluTermIoAttr(int fn)
{
  isTerminal = false;
  //--- init terminal attributes struct private member for stdin
  if (tcgetattr(fn, &attr) == 0) {
    //--- annotate whether the file handler corresponds to a terminal
    isTerminal = true;
  }
  printf("isTerminal %d, fn=%d\n", isTerminal?1:0, fn);
}

aluTermIoAttr::~aluTermIoAttr()
{
  //--- restore terminal with initial configuration
  if (isTerminal) {
    tcsetattr(fn, TCSAFLUSH, &attr);
  }
}

//--- setup input terminal to get immediately key-presses, with no echo
void aluTermIoAttr::SetImmedNoecho()
{
  struct termios attrNew;

  if (isTerminal) {
    memcpy(&attrNew, &attr, sizeof(attr));
    //--- echo off
    attrNew.c_lflag &= ~(ECHO);
    //--- do not wait for newline
    attrNew.c_lflag &= ~(ICANON);
    //--- read at least one char
    attrNew.c_cc[VMIN] = 1;
    // set new terminal attrs
    tcsetattr(fn, TCSAFLUSH, &attrNew);
  }
}

//--- setup input terminal to get immediately key-presses, with no echo
void aluTermIoAttr::SetSerialInput()
{
  struct termios attrNew;

  if (isTerminal) {
    memcpy(&attrNew, &attr, sizeof(attr));

    attrNew.c_cflag = B9600 | CRTSCTS | CS8 | CLOCAL | CREAD;
    attrNew.c_iflag = IGNPAR | IGNCR;
    attrNew.c_oflag = 0;
    attrNew.c_lflag = ICANON;
    attrNew.c_cc[VMIN]=1;
    attrNew.c_cc[VTIME]=0;
    tcflush(fn, TCIFLUSH);
    tcsetattr(fn,TCSANOW,&attrNew);
  }
}

void aluTermIoAttr::Reset()
{
  //--- restore terminal with initial configuration
  if (isTerminal) {
    tcsetattr(fn, TCSAFLUSH, &attr);
  }
}
